package com.hd.trans.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Build;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.CheckResult;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.GravityInt;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;

import com.hd.trans.R;
import com.hd.trans.widgets.ErrorTickView;
import com.hd.trans.widgets.SuccessTickView;


/**
 * Created by yang on 2018/1/20.
 * 在Toasty基础上修改而来
 */
@SuppressLint("InflateParams")
public class ToastUtils {

    @ColorInt
    private static int DEFAULT_TEXT_COLOR = Color.parseColor("#FFFFFF");
    @ColorInt
    private static int ERROR_COLOR = Color.parseColor("#D50000");
    @ColorInt
    private static int INFO_COLOR = Color.parseColor("#3F51B5");
    @ColorInt
    private static int SUCCESS_COLOR = Color.parseColor("#388E3C");
    @ColorInt
    private static int WARNING_COLOR = Color.parseColor("#FFA900");
    @ColorInt
    private static int NORMAL_COLOR = Color.parseColor("#353A3E");

    private static final Typeface LOADED_TOAST_TYPEFACE = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
    private static Typeface currentTypeface = LOADED_TOAST_TYPEFACE;
    private static int textSize = 16; // in SP

    private static boolean tintIcon = true;



    private ToastUtils(){ }

    private static Toast toast;
    private static Context mAppContext;



    public static synchronized void init(@NonNull Context context){
        mAppContext = context;
    }

    public final static String getString(@StringRes int resId, Object... formatArgs) {
        if(mAppContext!=null){
            return mAppContext.getString(resId, formatArgs);
        }else {
            return null;
        }
    }

    public static void hideToast(){
        if(toast != null){
            toast.cancel();
        }
    }

    public static void showNormalLong(String text, int duration){
        normal(mAppContext,text, duration).show();
    }
    public static void showNormal(String text){
        normal(mAppContext,text).show();
    }
    public static void showNormal(@StringRes int resId){
        normal(mAppContext,resId).show();
    }
    public static void showNormal(@StringRes int resId, Object... formatArgs){
        normal(mAppContext,getString(resId,formatArgs)).show();
    }

    public static void showSuccess(String text){
        success(mAppContext,text).show();
    }
    public static void showSuccess(@StringRes int resId){
        success(mAppContext,resId).show();
    }
    public static void showSuccess(@StringRes int resId, Object... formatArgs){
        success(mAppContext,getString(resId,formatArgs)).show();
    }

    public static void showError(String text){
        error(mAppContext,text).show();
    }
    public static void showError(@StringRes int resId){
        error(mAppContext,resId).show();
    }
    public static void showError(@StringRes int resId, Object... formatArgs){
        error(mAppContext,getString(resId,formatArgs)).show();
    }

    public static void showTop(String text){
        normalTop(mAppContext, text, Toast.LENGTH_SHORT, null, false).show();
    }
    public static void showTop(@StringRes int resId){
        normalTop(mAppContext, resId, Toast.LENGTH_SHORT, null, false).show();
    }

    public static void showBottom(String text){
        normalBottom(mAppContext, text, Toast.LENGTH_SHORT, null, false).show();
    }
    public static void showBottom(@StringRes int resId){
        normalBottom(mAppContext, resId, Toast.LENGTH_SHORT, null, false).show();
    }

    public static void showWarning(String text){
        warning(mAppContext,text).show();
    }
    public static void showInfo(String text){
        info(mAppContext,text).show();
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @StringRes int message) {
        return normal(context, context.getString(message), Toast.LENGTH_SHORT, null, false);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @NonNull CharSequence message) {
        return normal(context, message, Toast.LENGTH_SHORT, null, false);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @StringRes int message, Drawable icon) {
        return normal(context, context.getString(message), Toast.LENGTH_SHORT, icon, true);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @NonNull CharSequence message, Drawable icon) {
        return normal(context, message, Toast.LENGTH_SHORT, icon, true);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @StringRes int message, int duration) {
        return normal(context, context.getString(message), duration, null, false);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @NonNull CharSequence message, int duration) {
        return normal(context, message, duration, null, false);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @StringRes int message, int duration,
                                Drawable icon) {
        return normal(context, context.getString(message), duration, icon, true);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @NonNull CharSequence message, int duration,
                                Drawable icon) {
        return normal(context, message, duration, icon, true);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @StringRes int message, int duration,
                                Drawable icon, boolean withIcon) {
        return custom(context, context.getString(message), icon, NORMAL_COLOR, duration, withIcon, true);
    }

    @CheckResult
    private static Toast normal(@NonNull Context context, @NonNull CharSequence message, int duration,
                                Drawable icon, boolean withIcon) {
        return custom(context, message, icon, NORMAL_COLOR, duration, withIcon, true);
    }

    @CheckResult
    private static Toast normalTop(@NonNull Context context, @NonNull CharSequence message, int duration,
                                Drawable icon, boolean withIcon) {
        return custom(context, message, icon, Color.WHITE, duration, withIcon, true, Gravity.TOP);
    }

    @CheckResult
    private static Toast normalTop(@NonNull Context context, @StringRes int message, int duration,
                                   Drawable icon, boolean withIcon) {
        return custom(context, context.getString(message), icon, Color.WHITE, duration, withIcon, true, Gravity.TOP);
    }
    @CheckResult
    private static Toast normalBottom(@NonNull Context context, @NonNull CharSequence message, int duration,
                                Drawable icon, boolean withIcon) {
        return custom(context, message, icon, NORMAL_COLOR, duration, withIcon, true, Gravity.BOTTOM);
    }

    @CheckResult
    private static Toast normalBottom(@NonNull Context context, @StringRes int message, int duration,
                                   Drawable icon, boolean withIcon) {
        return custom(context, context.getString(message), icon, NORMAL_COLOR, duration, withIcon, true, Gravity.BOTTOM);
    }

    @CheckResult
    private static Toast warning(@NonNull Context context, @StringRes int message) {
        return warning(context, context.getString(message), Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast warning(@NonNull Context context, @NonNull CharSequence message) {
        return warning(context, message, Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast warning(@NonNull Context context, @StringRes int message, int duration) {
        return warning(context, context.getString(message), duration, true);
    }

    @CheckResult
    private static Toast warning(@NonNull Context context, @NonNull CharSequence message, int duration) {
        return warning(context, message, duration, true);
    }

    @CheckResult
    private static Toast warning(@NonNull Context context, @StringRes int message, int duration, boolean withIcon) {
        return custom(context, context.getString(message),  getDrawable(context, R.mipmap.toast_ic_warning),
                WARNING_COLOR, duration, withIcon, true);
    }

    @CheckResult
    private static Toast warning(@NonNull Context context, @NonNull CharSequence message, int duration, boolean withIcon) {
        return custom(context, message,  getDrawable(context, R.mipmap.toast_ic_warning),
                WARNING_COLOR, duration, withIcon, true);
    }

    @CheckResult
    private static Toast info(@NonNull Context context, @StringRes int message) {
        return info(context, context.getString(message), Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast info(@NonNull Context context, @NonNull CharSequence message) {
        return info(context, message, Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast info(@NonNull Context context, @StringRes int message, int duration) {
        return info(context, context.getString(message), duration, true);
    }

    @CheckResult
    private static Toast info(@NonNull Context context, @NonNull CharSequence message, int duration) {
        return info(context, message, duration, true);
    }

    @CheckResult
    private static Toast info(@NonNull Context context, @StringRes int message, int duration, boolean withIcon) {
        return custom(context, context.getString(message),  getDrawable(context, R.mipmap.toast_ic_info),
                INFO_COLOR, duration, withIcon, true);
    }

    @CheckResult
    private static Toast info(@NonNull Context context, @NonNull CharSequence message, int duration, boolean withIcon) {
        return custom(context, message,  getDrawable(context, R.mipmap.toast_ic_info),
                INFO_COLOR, duration, withIcon, true);
    }

    @CheckResult
    private static Toast success(@NonNull Context context, @StringRes int message) {
        return success(context, context.getString(message), Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast success(@NonNull Context context, @NonNull CharSequence message) {
        return success(context, message, Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast success(@NonNull Context context, @StringRes int message, int duration) {
        return success(context, context.getString(message), duration, true);
    }

    @CheckResult
    private static Toast success(@NonNull Context context, @NonNull CharSequence message, int duration) {
        return success(context, message, duration, true);
    }

    @CheckResult
    public static Toast success(@NonNull Context context, @StringRes int message, int duration, boolean withIcon) {
        return success(context, context.getString(message), duration, withIcon);
//        return custom(context, context.getString(message),  getDrawable(context, R.drawable.toast_ic_ok),
//                SUCCESS_COLOR, duration, withIcon, true);
    }

    @CheckResult
    public static Toast success(@NonNull Context context, @NonNull CharSequence message, int duration, boolean withIcon) {

//        return custom(context, message,  getDrawable(context, R.drawable.toast_ic_ok),
//                SUCCESS_COLOR, duration, withIcon, true);

        if (toast == null) {
            toast = Toast.makeText(context, "", duration);
        }else {
            try {
                IToastView toastV = (IToastView) toast.getView();
                if (toastV!=null){
                    toastV.cancel();
                }
            }catch (Exception e){
            }
            toast.cancel();
            toast = Toast.makeText(context, "", duration);
        }
        toast.setGravity(Gravity.CENTER, 0, 0);

//        final Toast currentToast = Toast.makeText(context, "", duration);
        final View toastLayout = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.toast_layout_success, null);
        final SuccessTickView toastSuccess = toastLayout.findViewById(R.id.success_tick);
        final TextView toastTextView = toastLayout.findViewById(R.id.toast_text);
        Drawable drawableFrame;
//        drawableFrame =  tint9PatchDrawableFrame(context, SUCCESS_COLOR);
        drawableFrame =  getDrawable(context, R.mipmap.toast_frame);
        setBackground(toastLayout, drawableFrame);

        toastTextView.setText(message);
        toastTextView.setTextColor(DEFAULT_TEXT_COLOR);
        toastTextView.setTypeface(currentTypeface);
        toastTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
        toast.setView(toastLayout);

        toastSuccess.startTickAnim();
        return toast;

    }

    @CheckResult
    private static Toast error(@NonNull Context context, @StringRes int message) {
        return error(context, context.getString(message), Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast error(@NonNull Context context, @NonNull CharSequence message) {
        return error(context, message, Toast.LENGTH_SHORT, true);
    }

    @CheckResult
    private static Toast error(@NonNull Context context, @StringRes int message, int duration) {
        return error(context, context.getString(message), duration, true);
    }

    @CheckResult
    private static Toast error(@NonNull Context context, @NonNull CharSequence message, int duration) {
        return error(context, message, duration, true);
    }

//    @CheckResult
//    private static Toast error(@NonNull Context context, @StringRes int message, int duration, boolean withIcon) {
//        return custom(context, context.getString(message),  getDrawable(context, R.drawable.toast_ic_error),
//                ERROR_COLOR, duration, withIcon, true);
//    }

    @CheckResult
    private static Toast error(@NonNull Context context, @NonNull CharSequence message, int duration, boolean withIcon) {
//        return custom(context, message,  getDrawable(context, R.drawable.toast_ic_error),
//                ERROR_COLOR, duration, withIcon, true);

        if (toast == null) {
            toast = Toast.makeText(context, "", duration);
        }else {
            try {
                IToastView toastV = (IToastView) toast.getView();
                if (toastV!=null){
                    toastV.cancel();
                }
            }catch (Exception e){
            }
            toast.cancel();
            toast = Toast.makeText(context, "", duration);
        }
        toast.setGravity(Gravity.CENTER, 0, 0);

//        final Toast currentToast = Toast.makeText(context, "", duration);
        final View toastLayout = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.toast_layout_error, null);
        final ErrorTickView toastError = toastLayout.findViewById(R.id.error_tick);
        final TextView toastTextView = toastLayout.findViewById(R.id.toast_text);
        Drawable drawableFrame;
//        drawableFrame =  tint9PatchDrawableFrame(context, ERROR_COLOR);
        drawableFrame =  getDrawable(context, R.mipmap.toast_frame);
        setBackground(toastLayout, drawableFrame);

        toastTextView.setText(message);
        toastTextView.setTextColor(DEFAULT_TEXT_COLOR);
        toastTextView.setTypeface(currentTypeface);
        toastTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
        toast.setView(toastLayout);

        toastError.startTickAnim();
        return toast;

    }

    @CheckResult
    private static Toast custom(@NonNull Context context, @StringRes int message, Drawable icon,
                                int duration, boolean withIcon) {
        return custom(context, context.getString(message), icon, -1, duration, withIcon, false);
    }

    @CheckResult
    private static Toast custom(@NonNull Context context, @NonNull CharSequence message, Drawable icon,
                                int duration, boolean withIcon) {
        return custom(context, message, icon, -1, duration, withIcon, false);
    }

    @CheckResult
    private static Toast custom(@NonNull Context context, @StringRes int message, @DrawableRes int iconRes,
                                @ColorInt int tintColor, int duration,
                                boolean withIcon, boolean shouldTint) {
        return custom(context, context.getString(message),  getDrawable(context, iconRes),
                tintColor, duration, withIcon, shouldTint);
    }

    @CheckResult
    private static Toast custom(@NonNull Context context, @NonNull CharSequence message, @DrawableRes int iconRes,
                                @ColorInt int tintColor, int duration,
                                boolean withIcon, boolean shouldTint) {
        return custom(context, message,  getDrawable(context, iconRes),
                tintColor, duration, withIcon, shouldTint);
    }

    @CheckResult
    private static Toast custom(@NonNull Context context, @StringRes int message, Drawable icon,
                                @ColorInt int tintColor, int duration,
                                boolean withIcon, boolean shouldTint) {
        return custom(context, context.getString(message), icon, tintColor, duration,
                withIcon, shouldTint);
    }

    @SuppressLint("ShowToast")
    @CheckResult
    private static Toast custom(@NonNull Context context, @NonNull CharSequence message, Drawable icon,
                                @ColorInt int tintColor, int duration,
                                boolean withIcon, boolean shouldTint) {

        if (toast == null) {
            toast = Toast.makeText(context, "", duration);
        }else {
            try {
                IToastView toastV = (IToastView) toast.getView();
                if (toastV!=null){
                    toastV.cancel();
                }
            }catch (Exception e){
            }
            toast.cancel();
            toast = Toast.makeText(context, "", duration);
        }
        toast.setGravity(Gravity.CENTER, 0, 0);

//        final Toast currentToast = Toast.makeText(context, "", duration);
        final View toastLayout = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.toast_layout, null);
        final ImageView toastIcon = toastLayout.findViewById(R.id.toast_icon);
        final TextView toastTextView = toastLayout.findViewById(R.id.toast_text);
        Drawable drawableFrame;

        if (shouldTint)
            drawableFrame =  tint9PatchDrawableFrame(context, tintColor);
        else
            drawableFrame =  getDrawable(context, R.mipmap.toast_frame);
        setBackground(toastLayout, drawableFrame);

        if (withIcon) {
            if (icon == null)
                throw new IllegalArgumentException("Avoid passing 'icon' as null if 'withIcon' is set to true");
            if (tintIcon)
                icon =  tintIcon(icon, DEFAULT_TEXT_COLOR);
             setBackground(toastIcon, icon);
        } else {
            toastIcon.setVisibility(View.GONE);
        }

        toastTextView.setText(message);
        toastTextView.setTextColor(DEFAULT_TEXT_COLOR);
        toastTextView.setTypeface(currentTypeface);
        toastTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);

        toast.setView(toastLayout);
        return toast;
    }

    @CheckResult
    private static Toast custom(@NonNull Context context, @NonNull CharSequence message, Drawable icon,
                                @ColorInt int tintColor, int duration, boolean withIcon, boolean shouldTint,
                                @GravityInt int gravity) {

        if (toast == null) {
            toast = Toast.makeText(context, "", duration);
        }else {
            try {
                IToastView toastV = (IToastView) toast.getView();
                if (toastV!=null){
                    toastV.cancel();
                }
            }catch (Exception e){
            }
            toast.cancel();
            toast = Toast.makeText(context, "", duration);
        }
        if(Gravity.CENTER == gravity){

            toast.setGravity(Gravity.CENTER, 0, 0);
        }else if (Gravity.TOP == gravity){
            toast.setGravity(Gravity.TOP, 0, 45);
        }else if (Gravity.BOTTOM == gravity){
            toast.setGravity(Gravity.BOTTOM, 0, 300);
        }

//        final Toast currentToast = Toast.makeText(context, "", duration);
        final View toastLayout = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.toast_layout, null);
        final ImageView toastIcon = toastLayout.findViewById(R.id.toast_icon);
        final TextView toastTextView = toastLayout.findViewById(R.id.toast_text);
        Drawable drawableFrame;

        if (shouldTint)
            drawableFrame =  tint9PatchDrawableFrame(context, tintColor);
        else
            drawableFrame =  getDrawable(context, R.mipmap.toast_frame);
        setBackground(toastLayout, drawableFrame);

        if (withIcon) {
            if (icon == null)
                throw new IllegalArgumentException("Avoid passing 'icon' as null if 'withIcon' is set to true");
            if (tintIcon)
                icon =  tintIcon(icon, DEFAULT_TEXT_COLOR);
            setBackground(toastIcon, icon);
        } else {
            toastIcon.setVisibility(View.GONE);
        }

        toastTextView.setText(message);
        toastTextView.setTextColor(DEFAULT_TEXT_COLOR);
        toastTextView.setTypeface(currentTypeface);
        toastTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);

        toast.setView(toastLayout);
        return toast;
    }

    private static Drawable tintIcon(@NonNull Drawable drawable, @ColorInt int tintColor) {
        drawable.setColorFilter(tintColor, PorterDuff.Mode.SRC_IN);
        return drawable;
    }

    private static Drawable tint9PatchDrawableFrame(@NonNull Context context, @ColorInt int tintColor) {
        final NinePatchDrawable toastDrawable = (NinePatchDrawable) getDrawable(context, R.mipmap.toast_frame);
        return tintIcon(toastDrawable, tintColor);
    }

    private static void setBackground(@NonNull View view, Drawable drawable) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            view.setBackground(drawable);
        else
            view.setBackgroundDrawable(drawable);
    }

    private static Drawable getDrawable(@NonNull Context context, @DrawableRes int id) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            return context.getDrawable(id);
        else
            return context.getResources().getDrawable(id);
    }



    public static class Config {
        @ColorInt
        private int DEFAULT_TEXT_COLOR = ToastUtils.DEFAULT_TEXT_COLOR;
        @ColorInt
        private int ERROR_COLOR = ToastUtils.ERROR_COLOR;
        @ColorInt
        private int INFO_COLOR = ToastUtils.INFO_COLOR;
        @ColorInt
        private int SUCCESS_COLOR = ToastUtils.SUCCESS_COLOR;
        @ColorInt
        private int WARNING_COLOR = ToastUtils.WARNING_COLOR;

        private Typeface typeface = ToastUtils.currentTypeface;
        private int textSize = ToastUtils.textSize;

        private boolean tintIcon = ToastUtils.tintIcon;

        private Config() {
            // avoiding instantiation
        }

        @CheckResult
        public static Config getInstance() {
            return new Config();
        }

        public static void reset() {
            ToastUtils.DEFAULT_TEXT_COLOR = Color.parseColor("#FFFFFF");
            ToastUtils.ERROR_COLOR = Color.parseColor("#D50000");
            ToastUtils.INFO_COLOR = Color.parseColor("#3F51B5");
            ToastUtils.SUCCESS_COLOR = Color.parseColor("#388E3C");
            ToastUtils.WARNING_COLOR = Color.parseColor("#FFA900");
            ToastUtils.currentTypeface = LOADED_TOAST_TYPEFACE;
            ToastUtils.textSize = 16;
            ToastUtils.tintIcon = true;
        }

        @CheckResult
        public Config setTextColor(@ColorInt int textColor) {
            DEFAULT_TEXT_COLOR = textColor;
            return this;
        }

        @CheckResult
        public Config setErrorColor(@ColorInt int errorColor) {
            ERROR_COLOR = errorColor;
            return this;
        }

        @CheckResult
        public Config setInfoColor(@ColorInt int infoColor) {
            INFO_COLOR = infoColor;
            return this;
        }

        @CheckResult
        public Config setSuccessColor(@ColorInt int successColor) {
            SUCCESS_COLOR = successColor;
            return this;
        }

        @CheckResult
        public Config setWarningColor(@ColorInt int warningColor) {
            WARNING_COLOR = warningColor;
            return this;
        }

        @CheckResult
        public Config setToastTypeface(@NonNull Typeface typeface) {
            this.typeface = typeface;
            return this;
        }

        @CheckResult
        public Config setTextSize(int sizeInSp) {
            this.textSize = sizeInSp;
            return this;
        }

        @CheckResult
        public Config tintIcon(boolean tintIcon) {
            this.tintIcon = tintIcon;
            return this;
        }

        public void apply() {
            ToastUtils.DEFAULT_TEXT_COLOR = DEFAULT_TEXT_COLOR;
            ToastUtils.ERROR_COLOR = ERROR_COLOR;
            ToastUtils.INFO_COLOR = INFO_COLOR;
            ToastUtils.SUCCESS_COLOR = SUCCESS_COLOR;
            ToastUtils.WARNING_COLOR = WARNING_COLOR;
            ToastUtils.currentTypeface = typeface;
            ToastUtils.textSize = textSize;
            ToastUtils.tintIcon = tintIcon;
        }
    }


}
